# -*- coding: utf-8 -*-

from django.template import Context, loader, RequestContext
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
from content_adm.models import Student, Course, Mark, Competence, CompinCrs, MarkforComp, Profession, CompforProf, Coefficient, Software
from math import ceil
from operator import itemgetter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase import ttfonts
from reportlab.lib.units import inch

# функция для перевода оценки из 100-бальной систему в 5-бальную
def convert(mark):
	if (mark.mark_final == 0):
		mark.mark_final = 3
	if (0 <= mark.mark_final <= 34):
		mark.mark_final = 3
	if (34 < mark.mark_final <= 67):
		mark.mark_final = 4
	if (67 < mark.mark_final <= 100):
		mark.mark_final = 5
	if (mark.mark_avg == 0):
		mark.mark_avg = 0
	if (0 < mark.mark_avg <= 34):
		mark.mark_avg = 3
	if (34 < mark.mark_avg <= 67):
		mark.mark_avg = 4
	if (67 < mark.mark_avg <= 100):
		mark.mark_avg = 5
	return mark

# функция для считываения оценок из формы и сохранения в базу
def get_save_marks(course_list, student, request):
	i = 1
	j = 1
	for course in course_list:
		try:														# считываем уточненные данные для уже существующих в базе оценок из
			mark = course.mark_set.get(stud=student.stud_id)		# формы, отправленной пользователем, приводим в 100-бальную систему,
			mf = 'mark_final_r' + str(i)							# сохраняем в базе
			ma = 'mark_avg_r' + str(i)							
			mark.mark_final = ceil((int(request.POST[mf]) - 2)*33.3)
#			mark.mark_avg = int(request.POST[ma])*20
			i = i + 1
			mark.save()
				
		except (Mark.DoesNotExist):									# считываем новые итоговые оценки из
			mark = Mark()											# формы, отправленной пользователем, приводим в 100-бальную систему,
			mark.crs = course										# сохраняем в базе
			mark.stud = student										
			mf = 'mark_final_w' + str(j)
			ma = 'mark_avg_w' + str(j)
			mark.mark_final = ceil((int(request.POST[mf]) - 2)*33.3)
			mark.mark_avg = 0
#			mark.mark_avg = int(request.POST[ma])*20
			j = j + 1
			mark.save()

# функция для вычисления взвешенного количества часов под каждую компетенцию в курсе
def hours_count(hlec,hprac,hlab,hself,cproj,percent):
	
	try:													# считаем количество часов с учетом их ценности, коэффициенты берем из базы
		sub_hours = 0.0											
		sub_hours += (Coefficient.objects.get(coef_name = "klec").coef_value)*hlec
		sub_hours += (Coefficient.objects.get(coef_name = "kprac").coef_value)*hprac
		sub_hours += (Coefficient.objects.get(coef_name = "klab").coef_value)*hlab
		sub_hours += (Coefficient.objects.get(coef_name = "kself").coef_value)*hself
		sub_hours += (Coefficient.objects.get(coef_name = "kself_cp").coef_value)*hself*cproj
							
	except:													# при отсутствии коэффициентов в базе берем дефолтные значения
		sub_hours = 0.0										
		sub_hours = sub_hours + (hlec*0.2)					# лекционные часы с коэффициентом 0.2
		sub_hours = sub_hours + (hprac*0.5)					# семинарские часы с коэффициентом 0.5
		sub_hours = sub_hours + (hlab*1)					# лабораторные часы с коэффициентом 1
		sub_hours = sub_hours + (hself*0.2)					# часы самостоятельной работы с коэффициентом 0.2
		sub_hours = sub_hours + (hself*cproj*0.5)			# бонус за часы самостоятельной работы при наличии курсового проекта - 0.5
															# (всего 0.7)

	sub_hours = (sub_hours * percent) / 100					# выделяем долю от общего числа часов по курсу для данной
	return sub_hours

# функция для вычисления оценки компетенции в курсе
def mark_count(mf,ma,mc):
	# Перебираем все варианты наличия/отсутствия оценок
	
	# есть итоговая оценка, нет оценок по компетенции и нет средней оценки
	if ((ma == 0) and (mc == 0) and (mf != 0)):
		mark_result = mf								# итоговая оценка с коэффициентом 1.0

	# есть средняя оценка, нет итоговой оценки, нет оценки по компетенции (случай зачета)
	if ((mf == 0) and (mc == 0) and (ma != 0)):
		mark_result = ma								# средняя оценка с коэффициентом 1.0

	# есть компетентная оценка, нет итоговой оценки, нет средней оценки (случай зачета)
	if ((mf == 0) and (ma == 0) and (mc != 0)):
		mark_result = mc								# компетентная оценка с коэффициентом 1.0

	# нет компетентной оценки, нет итоговой оценки, нет средней оценки (случай зачета)
	if ((mf == 0) and (ma == 0) and (mc == 0)):
		try:
			mark_result = Coefficient.objects.get(coef_name="z_mark_value").coef_value # значение дефолтного коэффициента "зачетной" оценки
		except:
			mark_result = 80							# константа 4

	# для всех прочих случаев коэффициенты берем из базы, в их отсутствие используем дефолтные

	# есть средняя оценка, есть компетентная оценка, нет оценки итоговой
	if ((ma != 0) and (mc != 0) and (mf == 0)):
		try:
			mark_result = (mc*(Coefficient.objects.get(coef_name="c_ac").coef_value)) + (ma*(Coefficient.objects.get(coef_name="a_ac").coef_value))
		except:
			mark_result = (ma*0.3) + (mc*0.7)			# средняя оценка - 0.3, компетентная - 0.7

	# есть итоговая оценка, есть средняя оценка, нет оценки по компетенции
	if ((ma != 0) and (mc == 0) and (mf != 0)):
		try:
			mark_result = (mf*(Coefficient.objects.get(coef_name="f_af").coef_value)) + (ma*(Coefficient.objects.get(coef_name="a_af").coef_value))
		except:
			mark_result = (mf*0.3) + (ma*0.7)			# итоговая оценка - 0.3, средняя - 0.7
				
	# есть итоговая оценка, есть оценка по компетенции, нет средней оценки
	if ((ma == 0) and (mc != 0) and (mf != 0)):
		try:
			mark_result = (mf*(Coefficient.objects.get(coef_name="f_cf").coef_value)) + (mc*(Coefficient.objects.get(coef_name="c_cf").coef_value))
		except:
			mark_result = (mf*0.3) + (mc*0.7)			# итоговая оценка - 0.3, по компетенции - 0.7
			
	# есть итоговая оценка, есть оценка по компетенции, есть средняя оценка
	if ((ma != 0) and (mc != 0) and (mf != 0)):
		try:
			mark_result = (mf*(Coefficient.objects.get(coef_name="f_acf").coef_value)) + (mc*(Coefficient.objects.get(coef_name="c_acf").coef_value)) + (ma*(Coefficient.objects.get(coef_name="a_acf").coef_value))
		except:
			mark_result = (mf*0.3) + (mc*0.7)			# итоговая оценка - 0.3, по компетенции - 0.7, средняя - 0.0
														# средняя оценка не учитывается
			
	return mark_result

# функция для вычисления взвешенной оценки компетенции по всем курсам
def total_mark_count(total_competence_hours,hours_mark_list):
	total_competence_result_hours = 0		
	if total_competence_hours > 0:
		for element in hours_mark_list:							# формируем взвешенную оценку с учетом часов
			mark = element[0]
			hours = element[1]
			weight_hours = (hours / total_competence_hours)
			total_competence_result_hours += (mark*weight_hours)
	else:
		total_competence_result_hours = 0
	return total_competence_result_hours

# функция подсчтеа максимального количества часов на компетенцию
def max_hours_count(calculate_list): 
	max_hours = 0												# максимальное количество часов на одну компетенцию
	for comp_element in calculate_list:
		a = comp_element.get('comp_hours')
		if (a > max_hours):
			max_hours = a
	return max_hours

# функция выставления итоговой оценрки для компетенций
def comp_mark_calculate(calculate_list, max_hours):
	
	clen = 0
	final_calculate_list = []										# список словарей, с итоговыми оценками для компетенций:
																	# comp_id - идентификатор компетенции
																	# comp_mark - оценка для компетенции
	for comp_element in calculate_list:
		if (comp_element.get('hours_way')) and (max_hours != 0):	# вариант с подсчетом часов
			comp_hours = comp_element.get('comp_hours')
			result_hours = comp_element.get('result_hours')
			comp_mark = (result_hours * comp_hours)/max_hours
		else:
			comp_mark = comp_element.get('result_k')				# вариант с коэффициентами от методиста
			if comp_mark > 100:
				comp_mark = 100

		comp_mark = round(comp_mark)
		i_comp_mark = int(comp_mark)
		
		dict_element = {'cmpt_id': comp_element.get('cmpt_id'), 'cmpt_short_name': comp_element.get('cmpt_short_name'), 'cmpt_mark': i_comp_mark}
		final_calculate_list.append(dict_element)
		clen += 1
	return {'final_calculate_list': final_calculate_list, 'clen': clen}

# функция выставления оценок по профессиям
def profession_list_calculate(final_calculate_list):
	profession_list = Profession.objects.all()
	resume_list = []
	plen = 0
	max_prof_mark = 0
	for profession in profession_list:
		compforprof_list = CompforProf.objects.filter(prof = profession.prof_id)
		comp_list = []
		prof_mark = 0.0
		for cp in compforprof_list:
			for element in final_calculate_list:
				cp_id = element.get('cmpt_id')
				if (cp_id == cp.cmpt.cmpt_id):
					c_name = element.get('cmpt_short_name')
					c_mark = element.get('cmpt_mark')
					comp_list_element = {'cmpt_id': cp_id, 'cmpt_name': c_name, 'k_importance': cp.importance, 'cmpt_mark': c_mark}
					comp_list.append(comp_list_element)
					prof_mark += (c_mark * cp.importance) / 100
		i_prof_mark = int(prof_mark)
		resume_list_element = {'prof_id': profession.prof_id, 'prof_name': profession.prof_name, 'prof_mark': i_prof_mark, 'cp_list': comp_list}
		if (i_prof_mark > max_prof_mark):
			mp_profession = resume_list_element
			max_prof_mark = i_prof_mark
		if (resume_list_element.get('prof_mark') > 0):
			plen += 1

		resume_list.append(resume_list_element)
		
	mp_profession['cp_list'] = sorted(mp_profession.get('cp_list'), key=itemgetter('cmpt_mark'), reverse=True)
	
	return {'resume_list': resume_list, 'mp_profession': mp_profession, 'plen': plen}

# функция получения параметров резюме
def get_all_info(request, length):
	fio = request.POST['i_fio']
	bd = request.POST['i_bd']
	city = request.POST['i_city']
	tel = request.POST['i_tel']
	mail = request.POST['i_mail']
	
	position = request.POST['i_position']
	sal = request.POST['i_sal']
	time = request.POST['i_time']
	
	inst = request.POST['i_inst']
	dep = request.POST['i_dep']
	year = request.POST['i_year']

	lang1 = request.POST['i_lang1']
	lang2 = request.POST['i_lang2']
	lang3 = request.POST['i_lang3']

	cmpt_list = []
	i_length = int(length)
	i_length += 1
	for item in range(1,i_length):
		name_getter = 'i_skill_name' + str(item)
		value_getter = 'i_skill_val' + str(item)
		name = request.POST[name_getter]
		value = request.POST[value_getter]
		cmpt_list.append({'name': name, 'value': value})
		
	soft = request.POST['i_soft']

	w1_org = request.POST['i_w1_org']
	w1_prof = request.POST['i_w1_prof']
	w1_beg = request.POST['i_w1_beg']
	w1_fin = request.POST['i_w1_fin']
	w2_org = request.POST['i_w2_org']
	w2_prof = request.POST['i_w2_prof']
	w2_beg = request.POST['i_w2_beg']
	w2_fin = request.POST['i_w2_fin']

	cnt = request.POST['i_cnt']
	perm = request.POST['i_perm']
	resume_type = request.POST['resume_type']

	resume_dict = {'fio': fio, 'bd': bd, 'city': city, 'tel': tel, 'mail': mail, 'position': position, 'sal': sal, 'time': time, 'inst': inst, 'dep': dep, 'year': year, 'lang1': lang1, 'lang2': lang2, 'lang3': lang3, 'cmpt_list': cmpt_list, 'soft': soft, 'w1_org': w1_org, 'w1_prof': w1_prof, 'w1_beg': w1_beg, 'w1_fin': w1_fin, 'w2_org': w2_org, 'w2_prof': w2_prof, 'w2_beg': w2_beg, 'w2_fin': w2_fin, 'cnt': cnt, 'perm': perm, 'resume_type': resume_type}
	return resume_dict

# функция получения необходимых данных по наиболее подходящей профессии	
def calculate_best_profession(mp_profession):
	mp_prof_name = mp_profession['prof_name']
	mp_mark = mp_profession['prof_mark']
	mp_prof_best_comp = mp_profession['cp_list'][0]['cmpt_name']
	mp_prof_best_comp_mark = mp_profession['cp_list'][0]['cmpt_mark']

	length = len(mp_profession['cp_list'])
	length = length - 1

	mp_prof_worst_comp = mp_profession['cp_list'][length]['cmpt_name']
	mp_prof_worst_comp_mark = mp_profession['cp_list'][length]['cmpt_mark']

	worst_comp_course_list = CompinCrs.objects.all().filter(cmpt = mp_profession['cp_list'][length]['cmpt_id'])
	worst_course_list = []	
	for item in worst_comp_course_list:
		worst_course_list.append(item.crs)
	length += 1

	mp_prof_cp_list = mp_profession['cp_list']
	software_list = []
	for item in mp_prof_cp_list:
		software = Software.objects.all().filter(cmpt = item['cmpt_id'])
		for element in software:
			software_list.append(element)

	mp = {'mp_prof_name': mp_prof_name, 'mp_prof_best_comp': mp_prof_best_comp, 'mp_prof_best_comp_mark': mp_prof_best_comp_mark, 'mp_prof_worst_comp': mp_prof_worst_comp, 'mp_prof_worst_comp_mark': mp_prof_worst_comp_mark, 'mp_mark': mp_mark, 'worst_course_list': worst_course_list, 'length': length, 'mp_prof_cp_list': mp_prof_cp_list, 'software_list': software_list}

	return mp

# функция отрисовки резюме в пдф документе
def prepare_canvas(p, resume_dict):
	MyFontObject_n = ttfonts.TTFont('timecyr', 't.ttf')
	MyFontObject_b = ttfonts.TTFont('timecyr_b', 'tb.ttf')
	MyFontObject_i = ttfonts.TTFont('timecyr_i', 'ti.ttf')
	MyFontObject_bi = ttfonts.TTFont('timecyr_bi', 'tbi.ttf')
	pdfmetrics.registerFont(MyFontObject_n)
	pdfmetrics.registerFont(MyFontObject_b)
	pdfmetrics.registerFont(MyFontObject_i)
	pdfmetrics.registerFont(MyFontObject_bi)
#		p.setFont("timecyr",9)

	textobject = p.beginText()
	textobject.setTextOrigin(inch, 11*inch)

	textobject.setFont("timecyr_b", 18)
	textobject.textLine(resume_dict['fio'])

	textobject.setFont("timecyr_i", 10)
	textobject.textLine(u'Дата рождения: ' + resume_dict['bd'])
	textobject.textLine(u'Город: ' + resume_dict['city'])
	textobject.textLine(u'Контактный телефон: ' + resume_dict['tel'])
	textobject.textLine(u'E-mail: ' + resume_dict['mail'])
	textobject.textLine()

	textobject.setFont("timecyr_b", 14)
	textobject.textLine("Желаемая должность и зарплата:")
	textobject.setFont("timecyr", 12)
	textobject.textLine(resume_dict['position'])
	if resume_dict['sal']:
		textobject.textLine(resume_dict['sal'])
	textobject.textLine(resume_dict['time'] + u' занятость')
	textobject.textLine()

	textobject.setFont("timecyr_b", 14)
	textobject.textLine("Образование:")
	textobject.setFont("timecyr", 12)
	textobject.textLine(resume_dict['year'] + u'  ' + resume_dict['inst'])
	textobject.textLine(resume_dict['dep'])
	textobject.textLine()
		
	textobject.setFont("timecyr_b", 14)
	textobject.textLine("Знание языков:")
	textobject.setFont("timecyr", 12)
	if resume_dict['lang1']:
		textobject.textLine(resume_dict['lang1'])
	if resume_dict['lang2']:
		textobject.textLine(resume_dict['lang2'])
	if resume_dict['lang3']:
		textobject.textLine(resume_dict['lang3'])
	textobject.textLine()
		
	textobject.setFont("timecyr_b", 14)
	textobject.textLine("Опыт работы:")
	textobject.setFont("timecyr", 12)
	if resume_dict['w1_org'] and resume_dict['w1_prof'] and resume_dict['w1_beg'] and resume_dict['w1_fin']:
		textobject.textLine(resume_dict['w1_org'] + u'        ' + resume_dict['w1_prof'] + u'        с ' + resume_dict['w1_beg'] + u' по ' + resume_dict['w1_fin'])
	if resume_dict['w2_org'] and resume_dict['w2_prof'] and resume_dict['w2_beg'] and resume_dict['w2_fin']:
		textobject.textLine(resume_dict['w2_org'] + u'        ' + resume_dict['w2_prof'] + u'        с ' + resume_dict['w2_beg'] + u' по ' + resume_dict['w2_fin'])
	textobject.textLine()

	textobject.setFont("timecyr_b", 14)
	textobject.textLine(u'Ключевые навыки (уровень подготовки):')
	textobject.setFont("timecyr", 12)
	for item in resume_dict['cmpt_list']:
		textobject.textLine(item['name'] + u' - ' + item['value'])
	textobject.textLine()
		
	textobject.setFont("timecyr", 12)
	textobject.textLine(u'Имеется опыт работы с ' + resume_dict['soft'])
	textobject.textLine()

	textobject.setFont("timecyr", 12)
	textobject.textLine(u'Гражданство: ' + resume_dict['cnt'])
	textobject.textLine(u'Разрешение на работу: ' + resume_dict['perm'])

	p.drawText(textobject)
	
	return p
